package engine.network
{
	import away3d.errors.*;
	import engine.core.*;
	import game.messages.*;
	
	import flash.utils.*;
	
	public class RxNetMessageBase
	{
		private static var s_idMap:Object = new Object();
		private static const UINTV_MIN:uint = 0;
		private static const UINTV_MAX:uint = (1 << 29) - 1;
		
		public function RxNetMessageBase()
		{
		}
		
		public static function RegisterMessage(id:uint, classname:Class) : void
		{
			if (s_idMap[id])
			{
				RxLog.Error("attempt to register duplicate message id: " + id);
			}
			else
			{
				s_idMap[id] = classname;
			}
		}
		
		public function GetId() : int
		{
			throw new AbstractMethodError();
		}
		
		public function GetBinarySize(param1:Number) : int
		{
			throw new AbstractMethodError();
		}
		
		public function IsFixedSize() : Boolean
		{
			throw new AbstractMethodError();
		}
		
		public function ToBinary(param1:ByteArray, param2:Number) : void
		{
			throw new AbstractMethodError();
		}
		
		public function FromBinary(param1:ByteArray, param2:Number) : void
		{
			throw new AbstractMethodError();
		}
		
		public static function GetMessageClass(param1:uint) : Class
		{
			return s_idMap[param1];
		}
		
		public static function GetSize_String(param1:String) : int
		{
			var _local2:uint = (param1==null ? 0 : param1.length);
			return (GetSize_uintv(_local2) + _local2);
		}
		
		public static function GetSize_uintv(param1:uint) : int
		{
			if (param1 < UINTV_MIN || param1 > UINTV_MAX)
			{
				throw new ArgumentError();
			}
			if (param1 < 1 << 7)
			{
				return 1;
			}
			if (param1 < 1 << 14)
			{
				return 2;
			}
			if (param1 < 1 << 21)
			{
				return 3;
			}
			return 4;
		}
		
		public static function Write_String(param1:ByteArray, param2:String) : void
		{
			var _loc_3:* = param2 == null ? (0) : (param2.length);
			Write_uintv(param1, _loc_3);
			if (_loc_3 > 0)
			{
				param1.writeUTFBytes(param2);
			}
		}
		
		public static function Write_uintv(param1:ByteArray, param2:uint) : void
		{
			var _loc_3:uint = 0;
			if (param2 < UINTV_MIN || param2 > UINTV_MAX)
			{
				throw new ArgumentError();
			}
			_loc_3 = param2 & 127;
			if (param2 > _loc_3)
			{
				_loc_3 = _loc_3 | 128;
			}
			param1.writeByte(_loc_3);
			param2 = param2 >> 7;
			if (param2 == 0)
			{
				return;
			}
			_loc_3 = param2 & 127;
			if (param2 > _loc_3)
			{
				_loc_3 = _loc_3 | 128;
			}
			param1.writeByte(_loc_3);
			param2 = param2 >> 7;
			if (param2 == 0)
			{
				return;
			}
			_loc_3 = param2 & 127;
			if (param2 > _loc_3)
			{
				_loc_3 = _loc_3 | 128;
			}
			param1.writeByte(_loc_3);
			param2 = param2 >> 7;
			if (param2 == 0)
			{
				return;
			}
			param1.writeByte(param2);
		}
		
		public static function Write_uint8(param1:ByteArray, param2:uint) : void
		{
			if (param2 > 255)
			{
				throw new ArgumentError();
			}
			param1.writeByte(param2);
		}
		
		public static function Read_String(param1:ByteArray) : String
		{
			var _loc_2:* = Read_uintv(param1);
			return _loc_2 == 0 ? (new String()) : (param1.readUTFBytes(_loc_2));
		}
		
		public static function Read_uintv(param1:ByteArray) : uint
		{
			var _loc_2:uint = 0;
			var _loc_3:uint = 0;
			_loc_2 = param1.readUnsignedByte();
			_loc_3 = _loc_3 | (_loc_2 & 127) << 0;
			if ((_loc_2 & 128) == 0)
			{
				return _loc_3;
			}
			_loc_2 = param1.readUnsignedByte();
			_loc_3 = _loc_3 | (_loc_2 & 127) << 7;
			if ((_loc_2 & 128) == 0)
			{
				return _loc_3;
			}
			_loc_2 = param1.readUnsignedByte();
			_loc_3 = _loc_3 | (_loc_2 & 127) << 14;
			if ((_loc_2 & 128) == 0)
			{
				return _loc_3;
			}
			_loc_2 = param1.readUnsignedByte();
			_loc_3 = _loc_3 | _loc_2 << 21;
			return _loc_3;
		}
		
		public static function Read_uint8(param1:ByteArray) : uint
		{
			return uint(param1.readByte()) & 255;
		}
		
		public static function GetSize_object_array(param1:*, param2:Class, param3:Number) : int
		{
			var _loc_7:int = 0;
			var _loc_8:RxNetMessageBase = null;
			var _loc_4:* = param1.length;
			var _loc_5:* = GetSize_uintv(_loc_4);
			var _loc_6:* = param2[RxRegisterAllMessages.s_fixedSizeIdentifier];
			if (param2[RxRegisterAllMessages.s_fixedSizeIdentifier])
			{
				_loc_7 = param2[RxRegisterAllMessages.s_binarySizeIdentifier];
				_loc_5 = _loc_5 + _loc_4 * _loc_7;
			}
			else
			{
				for each (_loc_8 in param1)
				{
					
					if (param2 != Object(_loc_8).constructor as Class)
					{
						throw new Error("all objects in the array must be of type " + param2);
					}
					_loc_5 = _loc_5 + _loc_8.GetBinarySize(param3);
				}
			}
			return _loc_5;
		}
		
		public static function Write_object_array(param1:ByteArray, param2:*, param3:Class, param4:Number) : void
		{
			var _loc_6:RxNetMessageBase = null;
			var _loc_5:* = param2.length;
			Write_uintv(param1, _loc_5);
			for each (_loc_6 in param2)
			{
				
				if (param3 != Object(_loc_6).constructor as Class)
				{
					throw new Error("all objects in the array must be of type " + param3);
				}
				_loc_6.ToBinary(param1, param4);
			}
		}
		
		public static function Read_object_array(param1:ByteArray, param2:*, param3:Class, param4:Number) : void
		{
			var _loc_7:RxNetMessageBase = null;
			var _loc_5:* = Read_uintv(param1);
			param2.length = _loc_5;
			var _loc_6:int = 0;
			while (_loc_6 < _loc_5)
			{
				
				_loc_7 = new param3;
				_loc_7.FromBinary(param1, param4);
				param2[_loc_6] = _loc_7;
				_loc_6++;
			}
		}
		
		public static function Write_int32(param1:ByteArray, param2:int) : void
		{
			param1.writeInt(param2);
		}
		
		public static function Read_int32(param1:ByteArray) : int
		{
			return param1.readInt();
		}
	}
}